package se.lnu.axez.physics.bullet;

import java.util.HashMap;
import java.util.Map;

import se.lnu.axez.FloatTriple;

public final class PhysicsManager {
	private final Map<String, CollisionShape> mCollisionShapes = new HashMap<String, CollisionShape>();
	private final Map<String, DiscreteDynamicsWorld> mDiscreteDynamicsWorlds = new HashMap<String, DiscreteDynamicsWorld>();
	
	public CollisionShape getOrCreateBoxCollisionShape(String name, float xSize, float ySize, float zSize) {
		if (!mCollisionShapes.containsKey(name)) {
			BoxCollisionShape collisionShape = new BoxCollisionShape(xSize, ySize, zSize);
			this.mCollisionShapes.put(name, collisionShape);
		}
		
		return mCollisionShapes.get(name);
	}

	public CollisionShape getOrCreateSphereCollisionShape(String name, float radius) {
		if (!mCollisionShapes.containsKey(name)) {
			SphereCollisionShape collisionShape = new SphereCollisionShape(radius);
			this.mCollisionShapes.put(name, collisionShape);
		}
		
		return mCollisionShapes.get(name);
	}
	
	public DiscreteDynamicsWorld getOrCreateDiscreteDynamicsWorld(String name, float xGravity, float yGravity, float zGravity) {
		if (!mDiscreteDynamicsWorlds.containsKey(name)) {
			DiscreteDynamicsWorld world = new DiscreteDynamicsWorld(FloatTriple.create(xGravity, yGravity, zGravity));
			this.mDiscreteDynamicsWorlds.put(name, world);
		}
		
		return mDiscreteDynamicsWorlds.get(name);
	}
	
	public PhysicsManager startWorldSimulations() {
		for (DiscreteDynamicsWorld world : mDiscreteDynamicsWorlds.values()) {
			world.startSimulation();
		}
		
		return this;
	}
	
	public PhysicsManager stopWorldSimulations() {
		for (DiscreteDynamicsWorld world : mDiscreteDynamicsWorlds.values()) {
			world.stopSimulation();
		}
		
		return this;
	}
	
	public PhysicsManager createAll() {
		final BulletFacade bulletFacade = BulletFacade.getInstance();
		
		for (CollisionShape shape : mCollisionShapes.values()) {
			shape.create(bulletFacade);
		}

		for (DiscreteDynamicsWorld world : mDiscreteDynamicsWorlds.values()) {
			world.create(bulletFacade);
		}

		return this;
	}
	
	public PhysicsManager destroyAll() {
		final BulletFacade bulletFacade = BulletFacade.getInstance();
		
		for (DiscreteDynamicsWorld world : mDiscreteDynamicsWorlds.values()) {
			world.destroy(bulletFacade);
		}
		
		mDiscreteDynamicsWorlds.clear();

		for (CollisionShape shape : mCollisionShapes.values()) {
			shape.destroy(bulletFacade);
		}
		
		mCollisionShapes.clear();
		
		return this;
	}
}
